import random
import sys
import pygame
from bullet import Bullet
from alien import IndependentAlien, Lined_Alien, DelayedAlien
from effects import Particle

def check_Keydown_events(event, ship):
    """响应按键"""
    if event.key == pygame.K_d:
        ship.moving_right = True
    elif event.key == pygame.K_a:
        ship.moving_left = True
    elif event.key == pygame.K_w:
        ship.moving_up = True
    elif event.key == pygame.K_s:
        ship.moving_down = True

def check_mousebuttondown_event(event, ai_settings, screen, ship, bullets):
    """响应鼠标事件"""
    current_time = pygame.time.get_ticks() / 1000  # 转换为秒
    if event.button == 1:
        if current_time - ai_settings.last_shot_time >= ai_settings.bullet_cooldown:    # 检查是否满足发射间隔
            # 创建一颗子弹，并将其加入到编组bullets中
            fire_bullet(ai_settings, screen, ship, bullets)
            ai_settings.last_shot_time = current_time

def check_mousebuttonup_event(event, ship):
    if event.button == 1:
        ship.ship_fire = False

def check_Keyup_events(event, ship):
    # 响应松开
    if event.key == pygame.K_d:
        ship.moving_right = False
    elif event.key == pygame.K_a:
        ship.moving_left = False
    elif event.key == pygame.K_w:
        ship.moving_up = False
    elif event.key == pygame.K_s:
        ship.moving_down = False

def check_events(ai_settings, screen, ship, bullets):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:  # (KEYDOWM:按下按键)
            check_Keydown_events(event, ship)
        elif event.type == pygame.KEYUP:  # (KEYUP:松开按键)
            check_Keyup_events(event, ship)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            check_mousebuttondown_event(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.MOUSEBUTTONUP:
            check_mousebuttonup_event(event, ship)

def fire_bullet(ai_settings, screen, ship, bullets):
    """如果没有到达限制，就可发射子弹"""
    # 创建一颗子弹，并将其加入到编组bullets中
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)
        ai_settings.fire_sound.play()
def update_bullets(bullets):
    """更新子弹的位置，并删除已消失的子弹"""
    # 更新子弹的位置
    bullets.update()
    # 删除屏幕外的子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)

def check_bullet_alien_collisions(ai_settings, screen, aliens, bullets, particles):
    # 检查子弹是否集中外星人
    # 如果是这样，就删除相应的子弹和外星人
    # 检测碰撞并删除子弹，但不自动删除外星人
    collisions = pygame.sprite.groupcollide(bullets, aliens, True, False)

    # 处理每个被击中的外星人
    for bullet, hit_aliens in collisions.items():
        # 播放击中音效
        if ai_settings.sound_on:
            ai_settings.hit_sound.play()

        for alien in hit_aliens:
            # 对每个外星人造成伤害
            is_destroyed = alien.take_damage(1)  # 假设take_damage方法返回是否被摧毁
            # 子弹击中效果
            for _ in range(10):
                color = (
                    255,  # R
                    random.randint(50, 150),  # G   (橙黄色范围)
                    0  # B
                )
                particles.add(Particle(
                    alien.rect.centerx,  # X坐标
                    alien.rect.centery,  # Y坐标
                    color  # 粒子颜色
                ))

            # 如果外星人被摧毁
            if is_destroyed:
                # 生成爆炸粒子效果
                for _ in range(50):
                    color = (
                        255,  # R
                        random.randint(50, 150),  # G   (橙黄色范围)
                        0  # B
                    )
                    particles.add(Particle(
                        alien.rect.centerx,  # X坐标
                        alien.rect.centery,  # Y坐标
                        color  # 粒子颜色
                    ))
                    # 烟雾粒子（灰色）
                    smoke_gray = random.randint(50, 150)
                    particles.add(Particle(
                        bullet.rect.centerx,
                        bullet.rect.centery,
                        (smoke_gray, smoke_gray, smoke_gray)
                    ))

                # 播放爆炸音效
                if ai_settings.sound_on:
                    ai_settings.explosion_sound.play()

                # 从组中移除外星人
                aliens.remove(alien)

    # 检查是否所有外星人都被消灭
    if len(aliens) == 0:
        # 清空子弹
        bullets.empty()

        # 创建新一波外星人
        create_mixed_fleet(ai_settings, screen, aliens)

def create_mixed_fleet(ai_settings, screen, aliens):
    """创建混合外星人群"""
    # 先清空现有外星人
    aliens.empty()

    # 创建列队外星人
    _create_formation_with_entrance(ai_settings, screen, aliens)

    # 创建独立外星人
    _create_roaming_aliens(ai_settings, screen, aliens)


def create_fleet_with_entrance(ai_settings, screen, aliens, init_y=-100):
    """
    创建从屏幕外飞入的外星人舰队
    参数:
        init_y: 初始Y坐标（屏幕上方外的位置）
    """
    # 使用临时外星人获取尺寸
    temp_alien = Lined_Alien(ai_settings, screen, 0, 0, 0, 0)
    alien_width = temp_alien.rect.width
    alien_height = temp_alien.rect.height

    # 计算舰队布局
    available_space_x = ai_settings.screen_width - 2 * alien_width
    number_aliens_x = int(available_space_x / (2 * alien_width))
    number_rows = 3

    # 清空现有外星人
    aliens.empty()

    # 从屏幕外生成
    for row in range(number_rows):
        for column in range(number_aliens_x):
            x = alien_width + 2 * alien_width * column
            target_y = alien_height + alien_height * row  # 目标位置
            delay_frames = column * 10  # 列延迟

            aliens.add(DelayedAlien(
                ai_settings=ai_settings,
                screen=screen,
                x=x,
                y=target_y,
                column=column,
                row=row,
                delay_frames=delay_frames,
                init_y=init_y  # 使用传入的初始Y坐标
            ))

def _create_formation_with_entrance(ai_settings, screen, aliens):
    """创建有入场动画的列队外星人"""
    # 使用临时外星人获取尺寸
    temp_alien = Lined_Alien(ai_settings, screen, 0, 0, 0, 0)
    alien_width = temp_alien.rect.width
    alien_height = temp_alien.rect.height

    # 计算舰队布局
    available_space_x = ai_settings.screen_width - 2 * alien_width
    number_cols = available_space_x // (2 * alien_width)
    number_rows = 3  # 外星人行数

    # 从屏幕外生成（每列有递增延迟）
    for row in range(number_rows):
        for col in range(number_cols):
            x = alien_width + 2 * alien_width * col
            target_y = alien_height + 2 * alien_height * row  # 最终目标Y坐标
            init_y = -alien_height * (row + 2)  # 初始在屏幕外

            # 每列增加延迟（第一列0帧，第二列10帧...）
            delay_frames = col * 10

            aliens.add(DelayedAlien(
                ai_settings=ai_settings,
                screen=screen,
                x=x,
                y=target_y,  # 注意这里传的是目标位置
                column=col,
                row=row,
                delay_frames=delay_frames,
                init_y=init_y  # 添加初始Y坐标
            ))

def _create_roaming_aliens(ai_settings, screen, aliens):
    count = 15
    for _ in range(count):
        aliens.add(IndependentAlien(ai_settings, screen))


def update_aliens(ai_settings, ship, aliens, enemy_bullets, particles):
    """更新所有外星人的状态"""
    # 更新位置和特殊行为
    for alien in aliens.sprites():
        alien.update()      # 每种外星人有自己的update方法

        # 独立外星人超出屏幕底部处理
        if isinstance(alien, IndependentAlien):       # # 检查是否是独立外星人（IndependentAlien类）
            _handle_roamer_boundary(alien, ai_settings, aliens)

    # 检测与飞船的碰撞
    _check_ship_collision(ai_settings, ship, aliens, enemy_bullets, particles)

def _handle_roamer_boundary(alien, ai_settings, aliens):
    """处理独立外星人边界逻辑"""
    if alien.rect.top >= ai_settings.screen_height:
        aliens.remove(alien)
        # 延迟1秒后生成新外星人
        pygame.time.set_timer(
            pygame.USEREVENT + 1,
            1000,   # 1秒延迟
            True    # 只触发一次
        )

def _check_ship_collision(ai_settings, ship, aliens, enemy_bullets, particles):
    """检测飞船碰撞"""
    current_time_crash = pygame.time.get_ticks() / 1000     # 转化为秒
    if pygame.sprite.spritecollideany(ship, aliens):
        if current_time_crash - ai_settings.last_crash_time >= ai_settings.crash_cooldown:  # 检查是否满足撞击扣血间隔
            if ai_settings.sound_on:
                ai_settings.crash_sound.play()
                ship.take_damage(1)
                ai_settings.last_crash_time = current_time_crash
                print("扣除1滴血量")

    ship_group = pygame.sprite.GroupSingle()
    ship_group.add(ship)
    collisions = pygame.sprite.groupcollide(enemy_bullets, ship_group, True, False)
    # 处理每次被击中
    for bullet, ship_list in collisions.items():    # 注意返回值是列表
        # 播放击中音效
        if ship_list:
            ai_settings.self_hit_sound.play()
        # 获取飞船对象（GroupSingle返回的列表也只有一个元素）
        ship = ship_list[0]
        hurt_hp = 1
        ship.take_damage(hurt_hp)     # 被击中扣除血量
        print(f"被击中！扣除{hurt_hp}滴血量")
        # 子弹击中效果
        for _ in range(15):
            # 火花粒子（橙黄色）
            particles.add(Particle(
                bullet.rect.centerx,
                bullet.rect.centery,
                (255, random.randint(100, 200), 0)
            ))
            # 烟雾粒子（灰色）
            smoke_gray = random.randint(50, 150)
            particles.add(Particle(
                bullet.rect.centerx,
                bullet.rect.centery,
                (smoke_gray, smoke_gray, smoke_gray)
            ))

def fire_enemy_bullets(aliens, enemy_bullets, current_time, ship):
    """敌军发射子弹"""
    # 敌军发射子弹（瞄准玩家）
    for alien in aliens:
        # 通用发射条件检查
        if (getattr(alien, 'can_shoot', False) and
                current_time - getattr(alien, 'last_shot_time', 0) >=
                getattr(alien, 'shoot_cooldown', 2000)):

            bullet = alien.try_shoot(current_time, ship)
            if bullet:
                enemy_bullets.add(bullet)

def update_bullet_positions(enemy_bullets, ai_settings):
    """更新子弹位置"""
    enemy_bullets.update()
    # 删除屏幕外的子弹
    for bullet in enemy_bullets.copy():
        if bullet.rect.top >= ai_settings.screen_height:
            enemy_bullets.remove(bullet)


def update_background(ai_settings, delta_time):
        """更新背景偏移量实现滚动"""
        # delta_time:上一帧耗时（秒），通过clock.tick()获取
        ai_settings.bg_offset_y += 1  # 向下滚动
        # 垂直滚动
        ai_settings.bg_offset_y += ai_settings.background_sroll_speed * delta_time * 60   # 每帧固定偏移量。
        # 高帧率时：每秒调用次数更多 → 累计偏移量更大 → 视觉速度更快
        # 低帧率时：每秒调用次数更少 → 累计偏移量更小 → 视觉速度更慢

        # 确保偏移量在合理范围内
        ai_settings.bg_offset_y = ai_settings.bg_offset_y % ai_settings.bg_height

def draw_background(ai_settings, screen):
    """平铺背景图覆盖整个窗口"""
    for x in range(-1, ai_settings.tiles_x + 1):
        for y in range(-1, ai_settings.tiles_y + 1):
            # 计算每张图的位置（考虑滚动偏移）
            pos_x = x * ai_settings.bg_width + ai_settings.bg_offset_x
            pos_y = y * ai_settings.bg_height + ai_settings.bg_offset_y
            screen.blit(ai_settings.bg_img, (pos_x, pos_y))

def update_screen(ai_settings, screen, ship, bullets, aliens, particles, enemy_bullets):
    """更新屏幕上的图像，并切换到新屏幕"""
    # 先绘制背景
    draw_background(ai_settings, screen)
    # 绘制顺序：背景 -> 子弹 -> 飞船/外星人 -> 粒子 -> UI
    bullets.draw(screen)
    enemy_bullets.draw(screen)
    # 绘制子弹拖尾
    for bullet in bullets:
        bullet.draw_trail(screen)

    ship.blitme()
    aliens.draw(screen)
    particles.draw(screen)

    # 让最近绘制的屏幕可见
    pygame.display.flip()

